package ca.scotthyndman.as2haxe.dom;

import java.util.HashSet;
import java.util.Set;

import ca.scotthyndman.as2haxe.dom.binding.BindingManager;

/**
 * Umbrella class for representing an abstract syntax tree.
 * 
 */
public class AST {

	private Set<ASTypeDeclaration> types = new HashSet<ASTypeDeclaration>();

	private Set<ASPackage> packages = new HashSet<ASPackage>();

	private BindingManager bindings = new BindingManager(this);

	public AST() {

	}

	/**
	 * Adds a type to the AST
	 * 
	 * @param type
	 */
	public void addType(ASTypeDeclaration type) {
		getTypes().add(type);
	}

	/**
	 * @return the types
	 */
	public Set<ASTypeDeclaration> getTypes() {
		return types;
	}

	/**
	 * Adds a package to the AST.
	 * 
	 * @param pkg
	 */
	public void addPackage(ASPackage pkg) {
		getPackages().add(pkg);
		getBindingManager().expose(pkg);
	}

	/**
	 * Returns all the packages in the AST.
	 * 
	 * @return the packages
	 */
	public Set<ASPackage> getPackages() {
		return packages;
	}

	/**
	 * Returns the binding manager.
	 * 
	 * @return the binding manager
	 */
	public BindingManager getBindingManager() {
		return bindings;
	}

	/**
	 * Exposes the AST's bindings.
	 */
	public void exposeBindings() {
		bindings.exposeBindings();
	}

	/**
	 * Links the AST's bindings.
	 */
	public void linkBindings() {
		bindings.linkBindings();
	}

	// ====== EVENTS

	/**
	 * Called before a child is replaced.
	 * 
	 * @param node
	 *            the parent node
	 * @param oldChild
	 *            the replaced child
	 * @param newChild
	 *            the new child
	 * @param property
	 *            the child's property
	 */
	public void preReplaceChildEvent(ASTNode node, ASTNode oldChild,
			ASTNode newChild, ASPropertyDescriptor property) {
		// TODO Event?
	}

	/**
	 * Called after a child is replaced.
	 * 
	 * @param node
	 *            the parent node
	 * @param oldChild
	 *            the replaced child
	 * @param newChild
	 *            the new child
	 * @param property
	 *            the child's property
	 */
	public void postReplaceChildEvent(ASTNode node, ASTNode oldChild,
			ASTNode newChild, ASPropertyDescriptor property) {
		// TODO Event?
	}

	/**
	 * Called before a child is removed.
	 * 
	 * @param node
	 *            the parent node
	 * @param oldChild
	 *            the replaced child
	 * @param property
	 *            the child's property
	 */
	public void preRemoveChildEvent(ASTNode node, ASTNode oldChild,
			ASPropertyDescriptor property) {
		// TODO Event?
	}

	/**
	 * Called before a child is removed.
	 * 
	 * @param node
	 *            the parent node
	 * @param oldChild
	 *            the replaced child
	 * @param property
	 *            the child's property
	 */
	public void postRemoveChildEvent(ASTNode node, ASTNode oldChild,
			ASPropertyDescriptor property) {
		// TODO Event?
	}

	/**
	 * Called before a child is added.
	 * 
	 * @param node
	 *            the parent node
	 * @param newChild
	 *            the new child
	 * @param property
	 *            the child's property
	 */
	public void preAddChildEvent(ASTNode node, ASTNode newChild,
			ASPropertyDescriptor property) {
		// TODO Event?
	}

	/**
	 * Called after a child is added.
	 * 
	 * @param node
	 *            the parent node
	 * @param newChild
	 *            the new child
	 * @param property
	 *            the child's property
	 */
	public void postAddChildEvent(ASTNode node, ASTNode newChild,
			ASPropertyDescriptor property) {
		// TODO Event?
	}

	public void preValueChangeEvent(ASTNode node, ASSimplePropertyDescriptor property) {
		// TODO Auto-generated method stub
		
	}

	public void postValueChangeEvent(ASTNode node, ASSimplePropertyDescriptor property) {
		// TODO Auto-generated method stub
		
	}
}
